package com.gakj.truck.third.core.utils;

import redis.clients.jedis.*;

import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class RedisClient {
    private static volatile JedisPool jedisPool;
    private static Lock lock = new ReentrantLock();

    public static final Integer TIME_DAY = 60 * 60 * 24;

    /**
     * 获取jedispool实例
     *
     * @return
     */
    public static JedisPool getInstance() {
        if (jedisPool == null) {
            try {
                lock.lock();
                if (jedisPool == null) {
                    JedisPoolConfig poolConfig = new JedisPoolConfig();
                    // 最多有5个空闲的实例
//					poolConfig.setMaxIdle(Integer.valueOf(PropUtil.getInstance().get("redis.maxIdle"))); 
                    //  分配了500个jedis实例后，pool的状态耗尽
//					poolConfig.setMaxTotal(Integer.valueOf(PropUtil.getInstance().get("redis.maxActive")));				
                    poolConfig.setMaxIdle(10);
                    poolConfig.setMaxTotal(200);
                    poolConfig.setMaxWaitMillis(3 * 1000);
                    String hostString = PropUtil.getInstance().get("redis.host");
                    String portString = PropUtil.getInstance().get("redis.port");
                    String timeoutString = PropUtil.getInstance().get("redis.timeout");
                    int port = Integer.parseInt(portString);
                    int timeout = Integer.parseInt(timeoutString);

                    jedisPool = new JedisPool(poolConfig, hostString, port, timeout);
                }
            } catch (Exception e) {

            } finally {
                lock.unlock();
            }
        }
        return jedisPool;

    }

    public static void cacheAdd(String key, String val, int seconds) {
        Jedis jedis = RedisClient.getInstance().getResource();
        jedis.set(key, val);
        jedis.expire(key, seconds);
        RedisClient.getInstance().returnResource(jedis);
//        close(jedis);
    }

    public static void cacheAdd(String key, String value) {
        Jedis jedis = RedisClient.getInstance().getResource();
        jedis.set(key, value);
        RedisClient.getInstance().returnResource(jedis);
//        RedisClient.getInstance().close();

    }

    public static void cacheDel(String key) {
        Jedis jedis = RedisClient.getInstance().getResource();
        jedis.del(key);
        RedisClient.getInstance().returnResource(jedis);
//        close(jedis);
    }

    public static boolean cacheExpire(String key, int seconds) {
        Jedis jedis = RedisClient.getInstance().getResource();
        long i = jedis.expire(key, seconds);
        RedisClient.getInstance().returnResource(jedis);
//        close(jedis);
        return i > 0;
    }

    public static String cacheReplace(String key, String val, int seconds) {
        Jedis jedis = RedisClient.getInstance().getResource();
        String str = jedis.set(key, val);
        jedis.expire(key, seconds);
        RedisClient.getInstance().returnResource(jedis);
//        close(jedis);
        return str;
    }

    public static String cacheGet(String key) {
        Jedis jedis = RedisClient.getInstance().getResource();
        String str = jedis.get(key);
        RedisClient.getInstance().returnResource(jedis);
//        close(jedis);
        return str;
    }

    public static void close(Jedis jedis) {
        jedis.close();
    }

    public static Long incr(String key) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long incr = jedis.incr(key);
        RedisClient.getInstance().returnResource(jedis);
        return incr;
    }

    public static Long desc(String key) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long decr = jedis.decr(key);
        RedisClient.getInstance().returnResource(jedis);
        return decr;
    }

    /**********************************
     * Map操作
     ***************************************************/

    public static String hget(String key, String field) {
        Jedis jedis = RedisClient.getInstance().getResource();
        String value = jedis.hget(key, field);
        RedisClient.getInstance().returnResource(jedis);
        return value;
    }

    public static void hset(String key, String field, String value) {
        Jedis jedis = RedisClient.getInstance().getResource();
        jedis.hset(key, field, value);
        RedisClient.getInstance().returnResource(jedis);
    }

    public static void hdel(String key, String field) {
        Jedis jedis = RedisClient.getInstance().getResource();
        jedis.hdel(key, field);
        RedisClient.getInstance().returnResource(jedis);
    }

    /**********************************
     * SortedSet
     **********************************************************/

    /**
     * 将 member 元素及其 score 值加入到有序集 key 当中
     * 如果某个 member 已经是有序集的成员，那么更新这个 member 的 score 值，
     * 并通过重新插入这个 member 元素，来保证该 member 在正确的位置上。
     * 如果 key 不存在，则创建一个空的有序集并执行 ZADD 操作。
     *
     * @param key
     * @param score
     * @param member
     * @return 被成功添加的新成员的数量，不包括那些被更新的、已经存在的成员
     */
    public static Long zadd(String key, double score, String member) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long zadd = jedis.zadd(key, score, member);
        RedisClient.getInstance().returnResource(jedis);
        return zadd;
    }

    /**
     * @param key    有序集的key值
     * @param score  增量
     * @param member 有序集的成员
     * @return member 成员的新 score 值，以字符串形式表示
     */
    public static Double zincrby(String key, double score, String member) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Double zincrby = jedis.zincrby(key, score, member);
        RedisClient.getInstance().returnResource(jedis);
        return zincrby;
    }

    /**
     * 指定区间内，带有 score 值(可选)的有序集成员的列表
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<String> zrange(String key, long start, long end) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Set<String> zrange = jedis.zrange(key, start, end);
        RedisClient.getInstance().returnResource(jedis);
        return zrange;
    }

    /**
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<Tuple> zrangeWithScores(String key, long start, long end) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Set<Tuple> tuples = jedis.zrangeWithScores(key, start, end);
        RedisClient.getInstance().returnResource(jedis);
        return tuples;
    }

    /**
     * 移除有序集key中,指定排名(rank)区间内的所有成员
     *
     * @param key
     * @param start
     * @param stop
     * @return 被移除成员的数量
     */
    public static Long zremrangebyrank(String key, long start, long stop) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long aLong = jedis.zremrangeByRank(key, start, stop);
        RedisClient.getInstance().returnResource(jedis);
        return aLong;
    }

    /**
     * 返回有序集key中成员member的排名,按从小到大佩列的
     *
     * @param key
     * @param member
     * @return
     */
    public static Long zrank(String key, String member) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long zrank = jedis.zrank(key, member);
        RedisClient.getInstance().returnResource(jedis);
        return zrank;
    }

    /**
     * 返回有序集key中member的排名,按从大到小排列
     *
     * @param key
     * @param member
     * @return
     */
    public static Long zrevrank(String key, String member) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long zrevrank = jedis.zrevrank(key, member);
        RedisClient.getInstance().returnResource(jedis);
        return zrevrank;
    }

    /**
     * 返回有序集key中,成员member的score值
     *
     * @param key
     * @param member
     * @return
     */
    public static double zscore(String key, String member) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Double zscore = jedis.zscore(key, member);
        RedisClient.getInstance().returnResource(jedis);
        return zscore;
    }

    /**
     * 返回有序集key中,score值再min和max之间的成员数量
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public static Long zcount(String key, double min, double max) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long zcount = jedis.zcount(key, min, max);
        RedisClient.getInstance().returnResource(jedis);
        return zcount;
    }

    /**
     * 移除有序集key中的一个或者多个成员
     *
     * @param key
     * @param member
     * @return 被移除的成员的数量, 不包括被忽略的成员
     */
    public static Long zrem(String key, String... member) {
        Jedis jedis = RedisClient.getInstance().getResource();
        Long zrem = jedis.zrem(key, member);
        RedisClient.getInstance().returnResource(jedis);
        return zrem;
    }

    /**
     * 用于迭代有序集合中的元素（包括元素成员和元素分值）
     *
     * @param key
     * @param cursor
     * @return
     */
    public static ScanResult<Tuple> zscan(String key, String cursor) {
        Jedis jedis = RedisClient.getInstance().getResource();
        ScanResult<Tuple> zscan = jedis.zscan(key, cursor);
        RedisClient.getInstance().returnResource(jedis);
        return zscan;
    }
}
